Program Listing for File mat_cerealisation.h
↰ Return to documentation for file (codes/pose_graph/utility/mat_cerealisation.h
)
#ifndef PROJECT_MAT_CEREALISATION_H
#define PROJECT_MAT_CEREALISATION_H
#include "cereal/cereal.hpp"
#include "opencv2/core/core.hpp"
//#include <cereal/archives/json.hpp>
namespace cereal {
template<class Archive, cereal::traits::DisableIf<cereal::traits::is_text_archive<Archive>::value>
= cereal::traits::sfinae>
void save(Archive& ar, const cv::Mat& mat)
{
int rows, cols, type;
bool continuous;
rows = mat.rows;
cols = mat.cols;
type = mat.type();
continuous = mat.isContinuous();
ar & rows & cols & type & continuous;
if (continuous) {
const int data_size = rows * cols * static_cast<int>(mat.elemSize());
auto mat_data = cereal::binary_data(mat.ptr(), data_size);
ar & mat_data;
}
else {
const int row_size = cols * static_cast<int>(mat.elemSize());
for (int i = 0; i < rows; i++) {
auto row_data = cereal::binary_data(mat.ptr(i), row_size);
ar & row_data;
}
}
};
template<class Archive, cereal::traits::DisableIf<cereal::traits::is_text_archive<Archive>::value>
= cereal::traits::sfinae>
void load(Archive& ar, cv::Mat& mat)
{
int rows, cols, type;
bool continuous;
ar & rows & cols & type & continuous;
if (continuous) {
mat.create(rows, cols, type);
const int data_size = rows * cols * static_cast<int>(mat.elemSize());
auto mat_data = cereal::binary_data(mat.ptr(), data_size);
ar & mat_data;
}
else {
mat.create(rows, cols, type);
const int row_size = cols * static_cast<int>(mat.elemSize());
for (int i = 0; i < rows; i++) {
auto row_data = cereal::binary_data(mat.ptr(i), row_size);
ar & row_data;
}
}
};
template <class Archive,
cereal::traits::EnableIf<cereal::traits::is_text_archive<Archive>::value>
= cereal::traits::sfinae>
void save(Archive& ar, const cv::Mat& mat)
{
int rows, cols, type;
bool continuous;
rows = mat.rows;
cols = mat.cols;
type = mat.type();
continuous = mat.isContinuous();
//ar & rows & cols & type & continuous;
assert(mat.dims == 2); // correct?
if (continuous) { // We go row by row anyway so no need for this distinction?
//const int data_size = rows * cols * static_cast<int>(mat.elemSize());
//std::vector<float> test(mat.begin<float>(), mat.end<float>());
//ar & test;
std::vector<std::vector<float>> mat_data;
for (int i = 0; i < rows; i++) {
cv::Mat this_row = mat.row(i); // need a temporary, otherwise goes up to 8GB RAM usage
mat_data.push_back(std::vector<float>(this_row.begin<float>(), this_row.end<float>()));
}
ar & cereal::make_nvp("data", mat_data); // Can we somehow not give this a name and make it like the "root" node, part of the parent object? Maybe look at the std::string serialisation?
}
else {
const int row_size = cols * static_cast<int>(mat.elemSize());
for (int i = 0; i < rows; i++) {
//auto row_data = cereal::binary_data(mat.ptr(i), row_size);
//ar & row_data;
}
}
};
template <class Archive,
cereal::traits::EnableIf<cereal::traits::is_text_archive<Archive>::value>
= cereal::traits::sfinae>
void load(Archive& ar, cv::Mat& mat)
{
//int rows, cols, type;
//bool continuous;
//ar & rows & cols & type & continuous;
std::vector<std::vector<float>> mat_data;
ar & mat_data;
assert(mat_data.size() > 0); // hmm can't store empty cv::Mat's... not so nice. Will create problems with SFM shape-only models?
int rows = static_cast<int>(mat_data.size());
int cols = static_cast<int>(mat_data[0].size());
mat.create(rows, cols, CV_32FC1);
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
mat.at<float>(r, c) = mat_data[r][c];
}
}
/* mat.create(rows, cols, type);
const int data_size = rows * cols * static_cast<int>(mat.elemSize());
auto mat_data = cereal::binary_data(mat.ptr(), data_size);
ar & mat_data;
mat.create(rows, cols, type);
const int row_size = cols * static_cast<int>(mat.elemSize());
for (int i = 0; i < rows; i++) {
auto row_data = cereal::binary_data(mat.ptr(i), row_size);
ar & row_data;
}*/
};
template <class Archive>
void serialize(Archive& ar, cv::Vec2f& vec)
{
ar(vec[0], vec[1]);
};
template <class Archive>
void serialize(Archive& ar, cv::Vec3f& vec)
{
ar(vec[0], vec[1], vec[2]);
};
/* serialization for CV KeyPoint */
template<class Archive>
inline void serialize(Archive& ar, cv::KeyPoint& kf)
{
ar(kf.angle, kf.class_id, kf.octave, kf.response, kf.pt.x, kf.pt.y);
}
// cv::Point
template<class Archive>
inline void serialize(Archive& ar, cv::Point& pt)
{
ar(pt.x, pt.y);
}
// cv::Point3f
template<class Archive>
inline void serialize(Archive& ar, cv::Point3f& pt)
{
ar(pt.x, pt.y, pt.z);
}
// cv::DMatch
template<class Archive>
inline void serialize(Archive& ar, cv::DMatch& match)
{
ar(match.queryIdx, match.trainIdx, match.imgIdx, match.distance);
}
} /* namespace cereal */
#endif //PROJECT_MAT_CEREALISATION_H